package com.hitqz.robot.camera.netty;

import com.hitqz.robot.camera.util.PelcodCameraToolkit;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;
import java.util.List;

/**
* 解码器
* */
@Slf4j
public class PelcodDecoder extends ByteToMessageDecoder {

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
        while (in.readableBytes() >= 7) { // 至少需要 7 字节
            in.markReaderIndex(); // 标记当前位置，方便回退

            // 检查消息头
            byte header0 = in.readByte();
            byte header1 = in.readByte();
            if (header0 != (byte) 0xFF || header1 != (byte) 0x01) {
                // 当前不是合法的消息头，继续查找
                skipToNextHeader(in);
                continue;
            }

            // 检查剩余字节数是否足够
            if (in.readableBytes() < 5) { // 剩余部分（命令字节 + 数据字节 + 校验和）
                in.resetReaderIndex(); // 数据不足，重置指针
                return; // 等待更多数据
            }

            // 读取完整帧
            byte[] cmd = new byte[2];
            in.readBytes(cmd); // 命令字节

            byte[] data = new byte[2];
            in.readBytes(data); // 数据部分

            byte checksum = in.readByte(); // 校验和

            // 创建消息对象
            PelcodMessage pelcodMessage = new PelcodMessage(cmd, data);

            // 校验帧是否完整
            if (pelcodMessage.getCheck() != checksum) {
                // 校验失败，尝试从剩余数据中查找下一个合法的消息头
                log.warn("[pelcod] Checksum failed, searching for next valid header.");
                skipToNextHeader(in);
                continue;
            }

            // 校验成功，传递消息
            out.add(pelcodMessage);
        }
    }

    /**
     * 从当前位置查找下一个合法的消息头（FF 01）
     */
    private void skipToNextHeader(ByteBuf in) {
        while (in.readableBytes() >= 2) { // 至少需要 2 字节判断协议头部
            in.markReaderIndex(); // 标记当前位置
            if (in.readByte() == (byte) 0xFF && in.readableBytes() > 0 && in.readByte() == (byte) 0x01) {
                // 找到消息头，回退到消息头开始位置
                in.resetReaderIndex();
                return;
            }
        }

        // 如果未找到合法消息头，清空 ByteBuf
        in.clear();
    }



}
